using Microsoft.Extensions.Configuration;
using System.Text.Json;
using System.Text.Json.Nodes;

namespace JGSY.CMS.LowCode.Platform.Infrastructure.Configuration
{
    /// <summary>
    /// 配置差异分析器
    /// </summary>
    public static class ConfigurationDifferenceAnalyzer
    {
        /// <summary>
        /// 比较两个配置文件的差异
        /// </summary>
        /// <param name="filePath1">第一个配置文件路径</param>
        /// <param name="filePath2">第二个配置文件路径</param>
        /// <returns>差异报告</returns>
        public static ConfigurationDifferenceReport CompareConfigurationFiles(string filePath1, string filePath2)
        {
            var report = new ConfigurationDifferenceReport
            {
                File1 = Path.GetFileName(filePath1),
                File2 = Path.GetFileName(filePath2),
                ComparedAt = DateTime.UtcNow
            };

            try
            {
                if (!File.Exists(filePath1))
                {
                    report.Errors.Add($"文件不存在: {filePath1}");
                    return report;
                }

                if (!File.Exists(filePath2))
                {
                    report.Errors.Add($"文件不存在: {filePath2}");
                    return report;
                }

                var json1 = File.ReadAllText(filePath1);
                var json2 = File.ReadAllText(filePath2);

                var obj1 = JsonSerializer.Deserialize<JsonObject>(json1);
                var obj2 = JsonSerializer.Deserialize<JsonObject>(json2);

                if (obj1 == null || obj2 == null)
                {
                    report.Errors.Add("无法解析 JSON 配置文件");
                    return report;
                }

                // 比较 Upload 配置
                CompareUploadConfiguration(obj1, obj2, report);

                // 比较 CloudStorage 配置
                CompareCloudStorageConfiguration(obj1, obj2, report);

                // 比较其他关键配置
                CompareOtherConfigurations(obj1, obj2, report);

                report.Status = report.HasDifferences() ? "有差异" : "一致";
            }
            catch (Exception ex)
            {
                report.Errors.Add($"配置比较失败: {ex.Message}");
                report.Status = "错误";
            }

            return report;
        }

        /// <summary>
        /// 分析存储配置的内部一致性
        /// </summary>
        /// <param name="configFilePath">配置文件路径</param>
        /// <returns>一致性报告</returns>
        public static StorageConsistencyReport AnalyzeStorageConsistency(string configFilePath)
        {
            var report = new StorageConsistencyReport
            {
                ConfigFile = Path.GetFileName(configFilePath),
                AnalyzedAt = DateTime.UtcNow
            };

            try
            {
                if (!File.Exists(configFilePath))
                {
                    report.Errors.Add($"配置文件不存在: {configFilePath}");
                    return report;
                }

                var json = File.ReadAllText(configFilePath);
                var obj = JsonSerializer.Deserialize<JsonObject>(json);

                if (obj == null)
                {
                    report.Errors.Add("无法解析 JSON 配置文件");
                    return report;
                }

                var uploadConfig = obj["Upload"]?.AsObject();
                var cloudStorageConfig = obj["CloudStorage"]?.AsObject();

                if (uploadConfig == null && cloudStorageConfig == null)
                {
                    report.Warnings.Add("未找到 Upload 或 CloudStorage 配置");
                    return report;
                }

                // 检查存储类型一致性
                CheckStorageTypeConsistency(uploadConfig, cloudStorageConfig, report);

                // 检查路径一致性
                CheckPathConsistency(uploadConfig, cloudStorageConfig, report);

                // 检查文件限制一致性
                CheckFileLimitConsistency(uploadConfig, cloudStorageConfig, report);

                // 检查扩展名一致性
                CheckExtensionConsistency(uploadConfig, cloudStorageConfig, report);

                // 检查功能特性一致性
                CheckFeatureConsistency(uploadConfig, cloudStorageConfig, report);

                report.Status = report.HasIssues() ? "有问题" : "一致";
                report.ConsistencyScore = CalculateConsistencyScore(report);
            }
            catch (Exception ex)
            {
                report.Errors.Add($"一致性分析失败: {ex.Message}");
                report.Status = "错误";
            }

            return report;
        }

        private static void CompareUploadConfiguration(JsonObject obj1, JsonObject obj2, ConfigurationDifferenceReport report)
        {
            var upload1 = obj1["Upload"]?.AsObject();
            var upload2 = obj2["Upload"]?.AsObject();

            if (upload1 == null && upload2 == null) return;

            if (upload1 == null)
            {
                report.Differences.Add(new ConfigurationDifference
                {
                    Section = "Upload",
                    Key = "整个配置段",
                    Value1 = "不存在",
                    Value2 = "存在",
                    Type = "Missing"
                });
                return;
            }

            if (upload2 == null)
            {
                report.Differences.Add(new ConfigurationDifference
                {
                    Section = "Upload",
                    Key = "整个配置段",
                    Value1 = "存在",
                    Value2 = "不存在",
                    Type = "Missing"
                });
                return;
            }

            CompareJsonObjects("Upload", upload1, upload2, report);
        }

        private static void CompareCloudStorageConfiguration(JsonObject obj1, JsonObject obj2, ConfigurationDifferenceReport report)
        {
            var cloud1 = obj1["CloudStorage"]?.AsObject();
            var cloud2 = obj2["CloudStorage"]?.AsObject();

            if (cloud1 == null && cloud2 == null) return;

            if (cloud1 == null)
            {
                report.Differences.Add(new ConfigurationDifference
                {
                    Section = "CloudStorage",
                    Key = "整个配置段",
                    Value1 = "不存在",
                    Value2 = "存在",
                    Type = "Missing"
                });
                return;
            }

            if (cloud2 == null)
            {
                report.Differences.Add(new ConfigurationDifference
                {
                    Section = "CloudStorage",
                    Key = "整个配置段",
                    Value1 = "存在",
                    Value2 = "不存在",
                    Type = "Missing"
                });
                return;
            }

            CompareJsonObjects("CloudStorage", cloud1, cloud2, report);
        }

        private static void CompareOtherConfigurations(JsonObject obj1, JsonObject obj2, ConfigurationDifferenceReport report)
        {
            var sectionsToCompare = new[] { "JWT", "Cache", "Sms", "ConnectionStrings" };

            foreach (var section in sectionsToCompare)
            {
                var sec1 = obj1[section]?.AsObject();
                var sec2 = obj2[section]?.AsObject();

                if (sec1 == null && sec2 == null) continue;

                if (sec1 == null || sec2 == null)
                {
                    report.Differences.Add(new ConfigurationDifference
                    {
                        Section = section,
                        Key = "整个配置段",
                        Value1 = sec1 == null ? "不存在" : "存在",
                        Value2 = sec2 == null ? "不存在" : "存在",
                        Type = "Missing"
                    });
                    continue;
                }

                CompareJsonObjects(section, sec1, sec2, report);
            }
        }

        private static void CompareJsonObjects(string section, JsonObject obj1, JsonObject obj2, ConfigurationDifferenceReport report)
        {
            var allKeys = obj1.Select(kv => kv.Key).Union(obj2.Select(kv => kv.Key)).ToHashSet();

            foreach (var key in allKeys)
            {
                var value1 = obj1.TryGetPropertyValue(key, out var v1) ? v1?.ToString() : null;
                var value2 = obj2.TryGetPropertyValue(key, out var v2) ? v2?.ToString() : null;

                if (value1 != value2)
                {
                    report.Differences.Add(new ConfigurationDifference
                    {
                        Section = section,
                        Key = key,
                        Value1 = value1 ?? "不存在",
                        Value2 = value2 ?? "不存在",
                        Type = value1 == null || value2 == null ? "Missing" : "Different"
                    });
                }
            }
        }

        private static void CheckStorageTypeConsistency(JsonObject? uploadConfig, JsonObject? cloudStorageConfig, StorageConsistencyReport report)
        {
            if (uploadConfig == null || cloudStorageConfig == null) return;

            var uploadType = uploadConfig["StorageType"]?.ToString();
            var cloudType = cloudStorageConfig["StorageType"]?.ToString();

            if (uploadType != cloudType)
            {
                report.Inconsistencies.Add(new ConsistencyIssue
                {
                    Category = "StorageType",
                    Description = $"存储类型不一致: Upload={uploadType}, CloudStorage={cloudType}",
                    Severity = "Warning"
                });
            }
            else
            {
                report.ConsistentItems.Add($"StorageType: {uploadType}");
            }
        }

        private static void CheckPathConsistency(JsonObject? uploadConfig, JsonObject? cloudStorageConfig, StorageConsistencyReport report)
        {
            if (uploadConfig == null || cloudStorageConfig == null) return;

            var uploadLocal = uploadConfig["Local"]?.AsObject();
            var cloudLocal = cloudStorageConfig["Local"]?.AsObject();

            if (uploadLocal == null || cloudLocal == null) return;

            // 检查 RootPath
            var uploadRootPath = uploadLocal["RootPath"]?.ToString();
            var cloudRootPath = cloudLocal["RootPath"]?.ToString();

            if (uploadRootPath != cloudRootPath)
            {
                report.Inconsistencies.Add(new ConsistencyIssue
                {
                    Category = "RootPath",
                    Description = $"根路径不一致: Upload={uploadRootPath}, CloudStorage={cloudRootPath}",
                    Severity = "Error"
                });
            }
            else
            {
                report.ConsistentItems.Add($"RootPath: {uploadRootPath}");
            }

            // 检查 BaseUrl
            var uploadBaseUrl = uploadLocal["BaseUrl"]?.ToString();
            var cloudBaseUrl = cloudLocal["BaseUrl"]?.ToString();

            if (uploadBaseUrl != cloudBaseUrl)
            {
                report.Inconsistencies.Add(new ConsistencyIssue
                {
                    Category = "BaseUrl",
                    Description = $"基础URL不一致: Upload={uploadBaseUrl}, CloudStorage={cloudBaseUrl}",
                    Severity = "Error"
                });
            }
            else
            {
                report.ConsistentItems.Add($"BaseUrl: {uploadBaseUrl}");
            }
        }

        private static void CheckFileLimitConsistency(JsonObject? uploadConfig, JsonObject? cloudStorageConfig, StorageConsistencyReport report)
        {
            if (uploadConfig == null || cloudStorageConfig == null) return;

            var uploadMaxSize = uploadConfig["MaxFileSize"]?.ToString();
            var cloudMaxSize = cloudStorageConfig["MaxFileSize"]?.ToString();

            if (uploadMaxSize != cloudMaxSize)
            {
                report.Inconsistencies.Add(new ConsistencyIssue
                {
                    Category = "MaxFileSize",
                    Description = $"最大文件大小不一致: Upload={uploadMaxSize}, CloudStorage={cloudMaxSize}",
                    Severity = "Warning"
                });
            }
            else
            {
                report.ConsistentItems.Add($"MaxFileSize: {uploadMaxSize}");
            }
        }

        private static void CheckExtensionConsistency(JsonObject? uploadConfig, JsonObject? cloudStorageConfig, StorageConsistencyReport report)
        {
            if (uploadConfig == null || cloudStorageConfig == null) return;

            // 检查 AllowedExtensions
            var uploadExtensions = uploadConfig["AllowedExtensions"]?.AsArray()?.Select(x => x?.ToString()).Where(x => x != null).ToArray();
            var cloudExtensions = cloudStorageConfig["AllowedExtensions"]?.AsArray()?.Select(x => x?.ToString()).Where(x => x != null).ToArray();

            if (uploadExtensions != null && cloudExtensions != null)
            {
                if (!uploadExtensions.OrderBy(x => x).SequenceEqual(cloudExtensions.OrderBy(x => x)))
                {
                    report.Inconsistencies.Add(new ConsistencyIssue
                    {
                        Category = "AllowedExtensions",
                        Description = $"允许的文件扩展名不一致",
                        Severity = "Warning"
                    });
                }
                else
                {
                    report.ConsistentItems.Add($"AllowedExtensions: {uploadExtensions.Length} 个扩展名");
                }
            }
        }

        private static void CheckFeatureConsistency(JsonObject? uploadConfig, JsonObject? cloudStorageConfig, StorageConsistencyReport report)
        {
            if (uploadConfig == null || cloudStorageConfig == null) return;

            var uploadLocal = uploadConfig["Local"]?.AsObject();
            var cloudLocal = cloudStorageConfig["Local"]?.AsObject();

            if (uploadLocal == null || cloudLocal == null) return;

            var features = new[]
            {
                "CreateDateFolders",
                "GenerateThumbnails"
            };

            foreach (var feature in features)
            {
                var uploadFeature = uploadConfig[feature]?.ToString() ?? uploadLocal[feature]?.ToString();
                var cloudFeature = cloudLocal[feature]?.ToString();

                if (uploadFeature != cloudFeature)
                {
                    report.Inconsistencies.Add(new ConsistencyIssue
                    {
                        Category = feature,
                        Description = $"{feature} 设置不一致: Upload={uploadFeature}, CloudStorage={cloudFeature}",
                        Severity = "Info"
                    });
                }
                else
                {
                    report.ConsistentItems.Add($"{feature}: {uploadFeature}");
                }
            }
        }

        private static int CalculateConsistencyScore(StorageConsistencyReport report)
        {
            var totalItems = report.ConsistentItems.Count + report.Inconsistencies.Count;
            if (totalItems == 0) return 100;

            var consistentCount = report.ConsistentItems.Count;
            return (int)Math.Round((double)consistentCount / totalItems * 100);
        }
    }

    /// <summary>
    /// 配置差异报告
    /// </summary>
    public class ConfigurationDifferenceReport
    {
        public string File1 { get; set; } = string.Empty;
        public string File2 { get; set; } = string.Empty;
        public DateTime ComparedAt { get; set; }
        public string Status { get; set; } = "未知";
        public List<ConfigurationDifference> Differences { get; set; } = new List<ConfigurationDifference>();
        public List<string> Errors { get; set; } = new List<string>();

        public bool HasDifferences() => Differences.Count > 0;
        public bool HasErrors() => Errors.Count > 0;
    }

    /// <summary>
    /// 配置差异项
    /// </summary>
    public class ConfigurationDifference
    {
        public string Section { get; set; } = string.Empty;
        public string Key { get; set; } = string.Empty;
        public string Value1 { get; set; } = string.Empty;
        public string Value2 { get; set; } = string.Empty;
        public string Type { get; set; } = string.Empty; // Different, Missing
    }

    /// <summary>
    /// 存储一致性报告
    /// </summary>
    public class StorageConsistencyReport
    {
        public string ConfigFile { get; set; } = string.Empty;
        public DateTime AnalyzedAt { get; set; }
        public string Status { get; set; } = "未知";
        public int ConsistencyScore { get; set; } = 0;
        public List<ConsistencyIssue> Inconsistencies { get; set; } = new List<ConsistencyIssue>();
        public List<string> ConsistentItems { get; set; } = new List<string>();
        public List<string> Errors { get; set; } = new List<string>();
        public List<string> Warnings { get; set; } = new List<string>();

        public bool HasIssues() => Inconsistencies.Count > 0 || Errors.Count > 0 || Warnings.Count > 0;
        public bool HasErrors() => Errors.Count > 0;
    }

    /// <summary>
    /// 一致性问题
    /// </summary>
    public class ConsistencyIssue
    {
        public string Category { get; set; } = string.Empty;
        public string Description { get; set; } = string.Empty;
        public string Severity { get; set; } = "Info"; // Error, Warning, Info
    }
}
